package cc.rengu.oltp.utility.util;

import cc.rengu.jradp.mods.dbs.Database;
import cc.rengu.oltp.utility.bean.PageInfo;
import cc.rengu.oltp.utility.bean.PageResult;
import cc.rengu.oltp.utility.bean.RecursionInfo;
import cc.rengu.oltp.utility.bean.RecursionResult;
import cc.rengu.utility.dbs.DataBasePool;
import cc.rengu.utility.dbs.DataBasePoolConfig;
import cc.rengu.utility.dbs.SqlSession;
import cc.rengu.utility.dbs.mysql.MysqlSequence;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import cc.rengu.utility.threadarea.ThreadVar;
import com.alibaba.fastjson.JSON;

import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 数据为操作工具类
 * Created by 王成 on 2017/11/13.
 */
public class DbsUtil {
    private final RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    /* 数据库超时时间 */
    private static final int DB_TIME_OUT = 5;
    /* 最大查询记录数 */
    public static final int MAX_FETCH_NUM = 10000;
    /* 条件判断逻辑与字符定义 */
    private static final String condAndSeparator = " and ";
    private static final String condOrSeparator = " or ";
    /* 括号 */
    private static final String leftBracket = "(";
    private static final String rightBracket = ")";
    /*  大于或等于 */
    private static final String greaterOrEqual = "&gt;=";
    /* 大于 */
    private static final String greater = "&gt;";
    /* 小于或等于 */
    private static final String lessOrEqual = "&lt;=";
    /* 小于 */
    private static final String less = "&lt;";
    /* SQL语法语句 */
    protected static String between = " between ";

    /* 数据库实例 */
    private Database dbInst;
    private Database dbTransactionInst;
    /* 数据库连接池 */
    private String dbPoolName;
    /* 数据库超时时间 */
    private int dbTimeOut;

    public DbsUtil(String dbPoolName, int dbTimeOut) {
        Object dbInstObject = ThreadVar.getVar("_IGAS_INNER_DBSUTIL_" + dbPoolName);
        Object dbTransactionInstObject = ThreadVar.getVar("_IGAS_INNER_DBSUTIL_TRANSACTION_" + dbPoolName);
        if (null == dbInstObject) {
            this.dbInst = new Database();
            ThreadVar.setVar("_IGAS_INNER_DBSUTIL_" + dbPoolName, this.dbInst);
        } else {
            this.dbInst = (Database) dbInstObject;
        }
        if (null == dbTransactionInstObject) {
            this.dbTransactionInst = new Database();
            ThreadVar.setVar("_IGAS_INNER_DBSUTIL_TRANSACTION_" + dbPoolName, this.dbTransactionInst);
        } else {
            this.dbTransactionInst = (Database) dbTransactionInstObject;
        }
        this.dbPoolName = dbPoolName;
        this.dbTimeOut = dbTimeOut;
    }

    public DbsUtil(String dbPoolName) {
        Object dbInstObject = ThreadVar.getVar("_IGAS_INNER_DBSUTIL_" + dbPoolName);
        Object dbTransactionInstObject = ThreadVar.getVar("_IGAS_INNER_DBSUTIL_TRANSACTION_" + dbPoolName);
        if (null == dbInstObject) {
            this.dbInst = new Database();
            ThreadVar.setVar("_IGAS_INNER_DBSUTIL_" + dbPoolName, this.dbInst);
        } else {
            this.dbInst = (Database) dbInstObject;
        }
        if (null == dbTransactionInstObject) {
            this.dbTransactionInst = new Database();
            ThreadVar.setVar("_IGAS_INNER_DBSUTIL_TRANSACTION_" + dbPoolName, this.dbTransactionInst);
        } else {
            this.dbTransactionInst = (Database) dbTransactionInstObject;
        }
        this.dbTimeOut = DB_TIME_OUT;
        this.dbPoolName = dbPoolName;
    }

    public Database getDbInst() {
        return dbInst;
    }

    public void setDbInst(Database dbInst) {
        this.dbInst = dbInst;
    }

    public Database getDbTransactionInst() {
        return dbTransactionInst;
    }

    public void setDbTransactionInst(Database dbTransactionInst) {
        this.dbTransactionInst = dbTransactionInst;
    }

    public String getDbPoolName() {
        return dbPoolName;
    }

    public void setDbPoolName(String dbPoolName) {
        this.dbPoolName = dbPoolName;
    }

    public int getDbTimeOut() {
        return dbTimeOut;
    }

    public void setDbTimeOut(int dbTimeOut) {
        this.dbTimeOut = dbTimeOut;
    }

    /**
     * 建立数据库连接
     *
     * @return 0-成功，其它-失败
     */
    private int dbsConnect() {
        int iReturnCode;
        if (null == dbPoolName || dbPoolName.isEmpty()) {
            rglog.error("database poolName is null.");
            return -1;
        } else {
            iReturnCode = dbInst.dbsConnect(dbPoolName, dbTimeOut);
            if (iReturnCode != 0) {
                rglog.error("connect database error,errCode={} errMsg={}", dbInst.dbsGetErrno(), dbInst.dbsGetError());
                return iReturnCode;
            }
        }
        return iReturnCode;
    }

    /**
     * 断开数据库连接
     *
     * @return 0-成功，其它-失败
     */
    private int dbsDisconnect() {
        int iReturnCode;
        iReturnCode = dbInst.dbsDisconnect();
        if (iReturnCode != 0) {
            rglog.error("disConnect database error,errCode={} errMsg={}", dbInst.dbsGetErrno(), dbInst.dbsGetError());
            return iReturnCode;
        }
        return iReturnCode;
    }

    /**
     * 数据库事务回滚
     */
    private void dbsRollback() {
        int iReturnCode;
        iReturnCode = dbInst.dbsRollback();
        if (iReturnCode != 0) {
            rglog.error("dbsRollback error,errCode={} errMsg={}", dbInst.dbsGetErrno(), dbInst.dbsGetError());
        }
    }

    /**
     * 数据库事务提交
     */
    private void dbsCommit() {
        int iReturnCode;
        iReturnCode = dbInst.dbsCommit();
        if (iReturnCode != 0) {
            rglog.error("dbsCommit database error,errCode={} errMsg={}", dbInst.dbsGetErrno(), dbInst.dbsGetError());
        }
    }

    /**
     * 无事务控制的SQL执行
     *
     * @param sqlStr 需要执行的SQL语句
     * @param in     数据库执行传入参数,当为NULL时，自动从XML树中取值
     * @param out    数据库执行结果，当为NULL时，自动将执行结果插入到XML树
     * @return 0-成功，其它-失败
     */
    public int dbsExecuteSql(String sqlStr, Object in, Object out) throws Exception {
        int iReturnCode;
        int dbErrCode = Database.DBS_SUCCESS;
        long txnTime = DateUtil.getCurrentTimeStamp();
        /* 根据传入参数组装动态SQL */
        if (null != sqlStr && !sqlStr.isEmpty()) {
            sqlStr = sqlStr.replaceAll(greaterOrEqual, ">=").replaceAll(lessOrEqual, "<=").replaceAll(greater, ">").replaceAll(less, "<");
            sqlStr = parseDynamicSqlString(sqlStr, in);
            rglog.debug("动态SQL解析耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            rglog.debug("执行SQL参数:{}", JSON.toJSONString(in));
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 连接数据库 */
            iReturnCode = dbsConnect();
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("dbsConnect error,iReturnCode:{},databasePool:{}", iReturnCode, dbPoolName);
                throw new Exception("获取数据库连接失败!");
            }
            rglog.debug("连接数据库耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 数据库SQL语句执行 */
            iReturnCode = dbInst.dbsExecuteSql(sqlStr, in, out, dbTimeOut);
            if (Database.DBS_SUCCESS != iReturnCode) {
                if (Database.DBS_NOT_FOUND == iReturnCode) {
                    dbErrCode = Database.DBS_NOT_FOUND;
                } else {
                    rglog.error("dbsExecuteSql error,iReturnCode:{},errCode={} errMsg={}", iReturnCode, dbInst.dbsGetErrno(), dbInst.dbsGetError());
                    dbsRollback();
                    dbsDisconnect();
                    return iReturnCode;
                }
            }
            rglog.debug("执行数据库SQL耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 数据库事务提交 */
            dbsCommit();
            rglog.debug("数据库提交数据耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 关闭数据库连接 */
            dbsDisconnect();
            rglog.debug("关闭数据库连接耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            return dbErrCode;
        } else {
            rglog.error("SQL语句为空！");
            return -1;
        }
    }

    /**
     * 数据库事务开始
     *
     * @return 0-成功，其它-失败
     */
    public int dbsBeginTransaction() {
        int iReturnCode;
        long txnTime = DateUtil.getCurrentTimeStamp();
        /* 连接数据库 */
        iReturnCode = dbTransactionInst.dbsConnect(dbPoolName, dbTimeOut);
        if (Database.DBS_SUCCESS != iReturnCode) {
            rglog.error("dbsConnect error,iReturnCode:{},databasePool:{}", iReturnCode, dbPoolName);
            return iReturnCode;
        }
        /* 开启数据库事务 */
        iReturnCode = dbTransactionInst.dbsBeginTransaction();
        if (Database.DBS_SUCCESS != iReturnCode) {
            rglog.error("dbsBeginTransaction error,iReturnCode:{}", iReturnCode);
            return iReturnCode;
        }
        rglog.debug("开启数据库事务耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
        return iReturnCode;
    }

    /**
     * 数据库事务SQL执行
     *
     * @param sqlStr 需要执行的SQL语句
     * @param in     数据库执行传入参数,当为NULL时，自动从XML树中取值
     * @param out    数据库执行结果，当为NULL时，自动将执行结果插入到XML树
     * @return 0-成功，其它-失败
     */
    public int dbsExecuteTransactionSql(String sqlStr, Object in, Object out) throws Exception {
        int iReturnCode;
        long txnTime = DateUtil.getCurrentTimeStamp();
        /* 根据传入参数组装动态SQL */
        if (null != sqlStr && !sqlStr.isEmpty()) {
            sqlStr = sqlStr.replaceAll(greaterOrEqual, ">=").replaceAll(lessOrEqual, "<=").replaceAll(greater, ">").replaceAll(less, "<");
            sqlStr = parseDynamicSqlString(sqlStr, in);
            rglog.debug("动态SQL解析耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            rglog.debug("执行SQL参数:{}", JSON.toJSONString(in));
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 数据库SQL语句执行 */
            iReturnCode = dbTransactionInst.dbsExecuteSql(sqlStr, in, out, dbTimeOut);
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("dbsExecuteSql error,iReturnCode:{},errCode={} errMsg={}", iReturnCode, dbTransactionInst.dbsGetErrno(), dbTransactionInst.dbsGetError());
                return iReturnCode;
            }
            rglog.debug("执行数据库事务SQL耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            return iReturnCode;
        } else {
            rglog.error("SQL语句为空！");
            return -1;
        }
    }

    /**
     * 数据库事务结束
     *
     * @param flag true-正常结束，false-异常结束
     * @return 0-成功，其它-失败
     */
    public int dbsEndTransaction(boolean flag) {
        int iReturnCode;
        /* 连接数据库 */
        long txnTime = DateUtil.getCurrentTimeStamp();
        try {
            /* 结束数据库事务 */
            iReturnCode = dbTransactionInst.dbsEndTransaction();
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("dbsEndTransaction error,iReturnCode:{}", iReturnCode);
                return iReturnCode;
            }
            if (flag) {
                /* 数据库事务提交 */
                iReturnCode = dbTransactionInst.dbsCommit();
                if (Database.DBS_SUCCESS != iReturnCode) {
                    rglog.error("dbsCommit error.iReturnCode:{}", iReturnCode);
                    dbsDisconnect();
                    return iReturnCode;
                }
            } else {
                /* 数据库事务回滚 */
                iReturnCode = dbTransactionInst.dbsRollback();
                if (Database.DBS_SUCCESS != iReturnCode) {
                    rglog.error("dbsDisconnect error.iReturnCode:{}", iReturnCode);
                    return iReturnCode;
                }
            }
        } finally {
            /* 关闭数据库连接 */
            iReturnCode = dbTransactionInst.dbsDisconnect();
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("dbsDisconnect error.iReturnCode:{}", iReturnCode);
            }
        }
        rglog.debug("结束数据库事务耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
        return iReturnCode;
    }

    /**
     * 打开数据库游标
     *
     * @param sqlStr SQL语句
     * @param in     传输参数，当为NULL时，直接从XML树中取值
     * @return null-失败，其它-成功
     */
    private SqlSession dbsOpenCursor(String sqlStr, Object in) {
        int iReturnCode;
        /* 连接数据库 */
        iReturnCode = dbsConnect();
        if (Database.DBS_SUCCESS != iReturnCode) {
            rglog.error("dbsConnect error,iReturnCode:{},databasePool:{}", iReturnCode, dbPoolName);
            return null;
        }
        /* 打开游标 */
        SqlSession session = dbInst.dbsOpenCursor(sqlStr, in, dbTimeOut);
        if (null == session) {
            rglog.error("open cursor error,errCode={} errMsg={}", dbInst.dbsGetErrno(), dbInst.dbsGetError());
            return null;
        }
        return session;
    }

    /**
     * 从数据库游标中取值
     *
     * @param out Fetch结果，当为NULL时，直接将值插入到XML树
     * @return 0、1403-成功，其它-失败
     */
    private int dbsFetchData(SqlSession session, Object out) {
        int iReturnCode;
        /* 从游标中获取数据 */
        iReturnCode = dbInst.dbsFetchCursor(session, out);
        if (Database.DBS_SUCCESS != iReturnCode && Database.DBS_NOT_FOUND != iReturnCode) {
            rglog.error("dbsFetchCursor error,iReturnCode:{},errCode={} errMsg={}", iReturnCode, dbInst.dbsGetErrno(), dbInst.dbsGetError());
            return iReturnCode;
        }
        return iReturnCode;
    }

    /**
     * 关闭游标
     *
     * @return 0-成功，其它-失败
     */
    private int dbsCloseCursor(SqlSession session) {
        int iReturnCode;
        /* 关闭游标 */
        iReturnCode = dbInst.dbsCloseCursor(session);
        if (iReturnCode != 0) {
            rglog.error("dbsCloseCursor error,errCode={} errMsg={}", dbInst.dbsGetErrno(), dbInst.dbsGetError());
            return iReturnCode;
        }
        return iReturnCode;
    }

    @Deprecated
    /**
     * 查询数据库集合
     * @param sqlStr SQL语句
     * @param in SQL执行传入参数,当为NULL时，自动从XML树中取值
     * @param clazz 数据库类名
     * @return List集合
     * @throws Exception 异常
     */
    public List<Object> dbsFetchListData(String sqlStr, Object in, Class clasz) throws Exception {
        return dbsFetchLimitListData(sqlStr, in, clasz);
    }

    /**
     * 查询数据库集合
     *
     * @param sqlStr SQL语句
     * @param in     SQL执行传入参数,当为NULL时，自动从XML树中取值
     * @param clazz  数据库类名
     * @return List集合
     * @throws Exception 异常
     */
    public List<Object> dbsFetchLimitListData(String sqlStr, Object in, Class clazz) throws Exception {
        int iReturnCode;
        int fetchNum = 0;
        boolean exceedsLimitFlag = false;
        List<Object> arrayList = new ArrayList<>();
        long txnTime = DateUtil.getCurrentTimeStamp();
        /* 根据传入参数组装动态SQL */
        if (null != sqlStr && !sqlStr.isEmpty()) {
            sqlStr = sqlStr.replaceAll(greaterOrEqual, ">=").replaceAll(lessOrEqual, "<=").replaceAll(greater, ">").replaceAll(less, "<");
            sqlStr = parseDynamicSqlString(sqlStr, in);
            rglog.debug("解析动态SQL耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            rglog.debug("执行SQL参数:{}", JSON.toJSONString(in));
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 打开游标 */
            SqlSession session = dbsOpenCursor(sqlStr, in);
            if (null == session) {
                rglog.error("open cursor error.iReturnCode:{}");
                throw new Exception("open cursor error.");
            }
            rglog.debug("打开数据库游标耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 从游标获取数据 */
            Object object = clazz.newInstance();
            while (true) {
                iReturnCode = dbsFetchData(session, object);
                if (Database.DBS_SUCCESS != iReturnCode && Database.DBS_NOT_FOUND != iReturnCode) {
                    rglog.error("fetch error.<{}:{}>", dbInst.dbsGetErrno(), dbInst.dbsGetError());
                    dbsCloseCursor(session);
                    dbsDisconnect();
                    throw new Exception("fetch data error.");
                } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                    break;
                } else {
                    arrayList.add(object);
                    object = clazz.newInstance();
                    fetchNum++;
                    if (MAX_FETCH_NUM < fetchNum) {
                        rglog.error("查询结果超出平台最大限制记录数:{},请使用分页查询!", MAX_FETCH_NUM);
                        exceedsLimitFlag = true;
                        break;
                    }
                }
            }
            rglog.debug("数据库Fetch Data执行耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 关闭游标 */
            iReturnCode = dbsCloseCursor(session);
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("close cursor error.iReturnCode:{}", iReturnCode);
                throw new Exception("close cursor error.");
            }
            rglog.debug("关闭数据库游标耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            txnTime = DateUtil.getCurrentTimeStamp();
            /* 关闭数据库连接 */
            iReturnCode = dbsDisconnect();
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("disconnect database error.iReturnCode:{}", iReturnCode);
                throw new Exception("disconnect database error.");
            }
            rglog.debug("关闭数据库连接耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
            if (exceedsLimitFlag){
                throw new Exception("EXCEED FETCH MAX LIMIT RECORD!");
            }
            return arrayList;
        } else {
            rglog.error("SQL语句为空!");
            return null;
        }
    }

    /**
     * 根据分页查询条件分页查询数据
     *
     * @param sqlStr   SQL语句
     * @param in       SQL执行传入参数,当为NULL时，自动从XML树中取值
     * @param clazz    数据库类名
     * @param pageInfo 分页信息
     * @return 分页查询结果
     * @throws Exception 异常
     */
    public PageResult dbsFetchPageListData(String sqlStr, Object in, Class clazz, PageInfo pageInfo) throws Exception {
        PageResult pageResult = new PageResult();
        /* 判断分页查询条件 */
        if (null == sqlStr || null == in || null == pageInfo || pageInfo.getPageIndex() < 0 || pageInfo.getPageSize() < 0) {
            rglog.error("分页查询条件不符合分页查询条件：{}", JSON.toJSONString(pageInfo));
            throw new Exception("分页查询条件不符合分页查询条件");
        }
        /* 校验条件对象是否存在rowno字段 */
        if (!pageQueryInputObjectCheck(in)) {
            rglog.error("分页查询条件不符合分页查询条件:{}", in.toString());
            throw new Exception("ROWNO NOT DEFINE ERROR");
        }
        /* 解析动态SQL */
        long txnTime = DateUtil.getCurrentTimeStamp();
        sqlStr = sqlStr.replaceAll(greaterOrEqual, ">=").replaceAll(lessOrEqual, "<=").replaceAll(greater, ">").replaceAll(less, "<");
        sqlStr = parseDynamicSqlString(sqlStr, in);
        /* 根据数据库类型拼接分页查询语句 */
        String pageSql = synthPageQuerySqlString(sqlStr, pageInfo);
        if (null == pageSql) {
            rglog.error("不支持当前数据库类型{}的分页查询!", dbInst.getDatabaseType());
            throw new Exception("不支持当前数据库类型的分页查询");
        }
        rglog.debug("拼接分页查询SQL耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
        txnTime = DateUtil.getCurrentTimeStamp();
        /* 根据SQL语句查询总记录数 */
        String totalSql;
        if (sqlStr.contains("FROM ")) {
            totalSql = "SELECT COUNT(1) INTO #totalRows " + sqlStr.substring(sqlStr.indexOf("FROM "));
        } else {
            totalSql = "SELECT COUNT(1) INTO #totalRows " + sqlStr.substring(sqlStr.indexOf("from "));
        }
        int conditonIndex = getMinConditionIndex(totalSql);
        totalSql = (0 == conditonIndex) ? totalSql : totalSql.substring(0, conditonIndex);
        int iReturnCode = dbsExecuteSql(totalSql, in, pageInfo);
        if (0 != iReturnCode) {
            rglog.error("获取查询总记录数失败,iReturnCode:{}", iReturnCode);
            return null;
        }
        float totalPage = ((float) pageInfo.getTotalRows()) / ((float) pageInfo.getPageSize());
        pageInfo.setTotalPage((int) Math.ceil(totalPage));
        pageResult.setPageInfo(pageInfo);
        //无数据直接返回
        if (pageInfo.getTotalPage() == 0) {
            if (pageInfo.getPageIndex() > pageInfo.getTotalPage()) {
                rglog.info("查询页码{}大于记录总页数{}", pageInfo.getPageIndex(), pageInfo.getTotalPage());
                throw new Exception("查询页码大于记录总页数");
            }
            List<Object> objectList = new ArrayList<>();
            pageResult.setResult(objectList);
            return pageResult;
        }
        if (pageInfo.getPageIndex() > pageInfo.getTotalPage()) {
            rglog.info("查询页码{}大于记录总页数{}", pageInfo.getPageIndex(), pageInfo.getTotalPage());
            throw new Exception("查询页码大于记录总页数");
        }
        rglog.debug("查询数据总记录耗时:{} ms", DateUtil.getCurrentTimeStamp() - txnTime);
        /* 根据分页查询SQL语句查询数据 */
        List<Object> objectList = dbsFetchLimitListData(pageSql, in, clazz);
        pageResult.setResult(objectList);
        return pageResult;
    }

    /**
     * 按照递归字段集合通过IN的方式进行分页查询
     *
     * @param sqlStr        SQL语句
     * @param in            SQL执行传入参数,当为NULL时，自动从XML树中取值
     * @param clazz         数据库类名
     * @param pageInfo      分页信息
     * @param recursionInfo 递归查询相关信息（对应实体类中的字段名）
     * @return 分页查询结果
     * @throws Exception 异常
     */
    public PageResult dbsRecursionPageQuery(String sqlStr, Object in, Class clazz, PageInfo pageInfo, RecursionInfo recursionInfo) throws Exception {
        /* 递归查询条件及条件值判断 */
        if (null == recursionInfo || StringUtil.isEmptyOrNull(recursionInfo.getConditionField()) ||
                null == recursionInfo.getRecursionValueList() || recursionInfo.getRecursionValueList().isEmpty()) {
            rglog.info("递归查询条件字段及条件值为空，默认不进行递归查询，只返回当前查询条件的对象列表!");
            return dbsFetchPageListData(sqlStr, in, clazz, pageInfo);
        }
        /* 判断分页查询条件 */
        if (null == sqlStr || null == in || null == pageInfo || pageInfo.getPageIndex() < 0 || pageInfo.getPageSize() < 0) {
            rglog.error("分页查询条件不符合分页查询条件：{}", JSON.toJSONString(pageInfo));
            throw new Exception("分页查询条件不符合分页查询条件");
        }
        /* 校验条件对象是否存在rowno字段 */
        if (!pageQueryInputObjectCheck(in)) {
            rglog.error("分页查询条件不符合分页查询条件:{}", in.toString());
            throw new Exception("ROWNO NOT DEFINE ERROR");
        }
        /* 解析动态SQL */
        sqlStr = sqlStr.replaceAll(greaterOrEqual, ">=").replaceAll(lessOrEqual, "<=").replaceAll(greater, ">").replaceAll(less, "<");
        sqlStr = parseDynamicSqlString(sqlStr, in);
        /* 将查询条件中的递归字段换成IN语句 */
        String conditionStr = "= $" + recursionInfo.getConditionField();
        List<String> recursionValueList = recursionInfo.getRecursionValueList().stream().sorted().collect(Collectors.toList());
        if (!recursionValueList.contains(StringUtil.getObjectFieldValue(in, recursionInfo.getConditionField()))) {
            recursionValueList.add(StringUtil.getObjectFieldValue(in, recursionInfo.getConditionField()));
        }
        StringBuilder stringBuilder = new StringBuilder("IN (");
        for (String item : recursionInfo.getRecursionValueList()) {
            stringBuilder.append("'").append(item).append("',");
        }
        String replateStr = stringBuilder.substring(0, stringBuilder.toString().length() - 1) + ")";
        sqlStr = sqlStr.replace(conditionStr, replateStr);
        return dbsFetchPageListData(sqlStr, in, clazz, pageInfo);
    }

    /**
     * 根据递归字段集合按照递归字段分片查询（按照递归字段值逐个查询并拼装返回分页信息）
     *
     * @param sqlStr        SQL语句
     * @param in            SQL执行传入参数,当为NULL时，自动从XML树中取值
     * @param clazz         数据库类名
     * @param pageInfo      分页信息
     * @param recursionInfo 递归查询相关信息（对应实体类中的字段名）
     * @return 分页查询结果
     * @throws Exception 异常
     */
    public PageResult dbsRecursionShardQuery(String sqlStr, Object in, Class clazz, PageInfo pageInfo, RecursionInfo recursionInfo) throws Exception {
        PageResult pageResult = new PageResult();
        /* 解析动态SQL */
        sqlStr = sqlStr.replaceAll(greaterOrEqual, ">=").replaceAll(lessOrEqual, "<=").replaceAll(greater, ">").replaceAll(less, "<");
        sqlStr = parseDynamicSqlString(sqlStr, in);
        /* 拼装查询总记录数的SQL */
        String conditionField = StringUtil.camelToUnderScoreString(recursionInfo.getConditionField());
        String conditionStr = "SELECT " + conditionField + ",COUNT(1) INTO #conditionField,#totalNum ";
        conditionStr += sqlStr.contains("FROM ") ? sqlStr.substring(sqlStr.indexOf("FROM ")) : sqlStr.substring(sqlStr.indexOf("from "));
        /* 去掉查询条件中的递归字段条件 */
        int begIndex = conditionStr.lastIndexOf(" AND " + conditionField);
        if (begIndex <= 0) {
            begIndex = conditionStr.lastIndexOf(" and " + conditionField);
        }
        int endIndex = conditionStr.lastIndexOf(recursionInfo.getConditionField());
        String totalSql = conditionStr.substring(0, begIndex) + conditionStr.substring(endIndex + recursionInfo.getConditionField().length());
        /* 去掉查询语句中的ORDER BY语句 */
        if (totalSql.contains(" ORDER ")) {
            totalSql = totalSql.substring(0, totalSql.lastIndexOf(" ORDER "));
        } else if (totalSql.contains(" order ")) {
            totalSql = totalSql.substring(0, totalSql.lastIndexOf(" order "));
        }
        totalSql += " GROUP BY " + conditionField;
        List<Object> objectList = dbsFetchLimitListData(totalSql, in, RecursionResult.class);
        if (null == objectList || objectList.isEmpty()) {
            rglog.info("按照递归查询条件统计出来的查询记录为空!");
            return null;
        }
        List<RecursionResult> recursionResultList = objectList.stream().map(item -> (RecursionResult) item).collect(Collectors.toList());
        /* 只取递归参数传入的汇总数据并进行排序 */
        recursionResultList = recursionResultList.stream().filter(item -> recursionInfo.getRecursionValueList().contains(item.getConditionField())).collect(Collectors.toList());
        recursionResultList = recursionResultList.stream().sorted(Comparator.comparing(RecursionResult::getConditionField)).collect(Collectors.toList());
        /* 计算查询数据的总记录数 */
        int totalNum = recursionResultList.stream().mapToInt(RecursionResult::getTotalNum).sum();
        int totalPage = totalNum / pageInfo.getPageSize();
        pageInfo.setTotalPage((int) Math.ceil(totalPage));
        pageInfo.setTotalRows(totalNum);
        pageResult.setPageInfo(pageInfo);
        if (pageInfo.getTotalPage() == 0) {
            if (pageInfo.getPageIndex() > pageInfo.getTotalPage()) {
                rglog.info("查询页码{}大于记录总页数{}", pageInfo.getPageIndex(), pageInfo.getTotalPage());
                throw new Exception("查询页码大于记录总页数");
            }
            return pageResult;
        }
        if (pageInfo.getPageIndex() > pageInfo.getTotalPage()) {
            rglog.info("查询页码{}大于记录总页数{}", pageInfo.getPageIndex(), pageInfo.getTotalPage());
            throw new Exception("查询页码大于记录总页数");
        }
        /* 根据查询位置遍历查询数据 */
        int queryStartIndex = pageInfo.getPageIndex() * pageInfo.getPageSize();
        int totalQueryNum = 0;
        int queryOffset;
        for (RecursionResult item : recursionResultList) {
            totalQueryNum += item.getTotalNum();
            if (totalQueryNum > queryStartIndex) {
                StringUtil.setObjectFieldValue(in, recursionInfo.getConditionField(), item.getConditionField());
                queryOffset = item.getTotalNum() - (totalQueryNum - queryStartIndex);
                PageInfo queryPageInfo = new PageInfo();
                queryPageInfo.setPageIndex(queryOffset / pageInfo.getPageSize());
                queryPageInfo.setPageSize(pageInfo.getPageSize());
                PageResult queryPageResult = dbsFetchPageListData(sqlStr, in, clazz, queryPageInfo);
                if (null != queryPageResult && null != queryPageResult.getResult() && !queryPageResult.getResult().isEmpty()) {
                    if (null != pageResult.getResult()) {
                        int subIndex = Math.min(pageInfo.getPageSize() - pageResult.getResult().size(), queryPageResult.getResult().size());
                        pageResult.getResult().addAll(queryPageResult.getResult().subList(0, subIndex));
                    } else {
                        pageResult.setResult(queryPageResult.getResult());
                    }
                }
                if (pageResult.getResult().size() < pageInfo.getPageSize()) {
                    queryStartIndex += pageResult.getResult().size();
                } else {
                    break;
                }
            }
        }
        return pageResult;
    }

    /**
     * 单表递归查询
     *
     * @param sqlStr         SQL语句
     * @param in             SQL执行传入参数,当为NULL时，自动从XML树中取值
     * @param clazz          数据库类名
     * @param queryCondition 递归查询字段名
     * @param recursionField 后续递归取值对应字段名
     * @return 递归查询结果
     * @throws Exception 异常
     */
    public List<Object> dbsRecursionQuery(String sqlStr, Object in, Class clazz, String queryCondition, String recursionField) throws Exception {
        List<Object> queryResult = new ArrayList<>();
        List<Object> objects = dbsFetchLimitListData(sqlStr, in, clazz);
        if (null != objects && !objects.isEmpty()) {
            queryResult.addAll(objects);
            for (Object item : objects) {
                String value = StringUtil.getObjectFieldValue(item, recursionField);
                if (!StringUtil.isEmptyOrNull(value)) {
                    StringUtil.setObjectFieldValue(in, queryCondition, value);
                    List<Object> objectList = dbsRecursionQuery(sqlStr, in, clazz, queryCondition, recursionField);
                    if (null != objectList && !objectList.isEmpty()) {
                        queryResult.addAll(objectList);
                    }
                }
            }
        }
        return queryResult;
    }

    /**
     * 根据SEQUENCE名获取对应SEQUENCE的下一个值
     *
     * @param dbPoolName   数据库连接池名称
     * @param sequenceName SEQUENCE名称
     * @param length       SEQUENCE长度
     * @return SEQUENCE字符串
     */
    public String getSequenceNextValue(String dbPoolName, String sequenceName, int length) throws SQLException {
        MysqlSequence mysqlSequence = new MysqlSequence();
        long sequenceId = mysqlSequence.getNextValue(sequenceName, dbPoolName);
        return String.format("%0" + length + "d", sequenceId);
    }

    /**
     * 根据数据库类型及分页查询信息合成分页查询SQL
     *
     * @param sqlStr   原始SQL
     * @param pageInfo 分页查询信息
     * @return 合成的分页查询SQL
     */
    private String synthPageQuerySqlString(String sqlStr, PageInfo pageInfo) {
        String pageSql = null;
        int beginRowIndex = pageInfo.getPageIndex() * pageInfo.getPageSize();
        int endRowIndex = (pageInfo.getPageIndex() + 1) * pageInfo.getPageSize();
        if (DataBasePoolConfig.DB_TYPE_DB2 == DataBasePool.getSessionType(this.dbPoolName)) {
            String sqlTmp = sqlStr.replaceAll("INTO", "INTO \n #rowno,").replaceAll("into", "into \n #rowno,");
            int conditonIndex = getMinConditionIndex(sqlTmp);
            if (0 == conditonIndex) {
                pageSql = "SELECT * FROM (" +
                        "SELECT ROWNUMBER() OVER() AS rowno, tableAlias.* FROM (\n" + sqlTmp +
                        "\n) AS tableAlias) WHERE rowno BETWEEN " + ++beginRowIndex + " AND " + endRowIndex;
            } else {
                pageSql = "SELECT * FROM (" +
                        "SELECT ROWNUMBER() OVER() AS rowno, tableAlias.* FROM (\n" + sqlTmp.substring(0, conditonIndex) +
                        "\n) AS tableAlias) WHERE rowno BETWEEN " + ++beginRowIndex + " AND " + endRowIndex + " " + sqlTmp.substring(conditonIndex);
            }
        } else if (DataBasePoolConfig.DB_TYPE_ORACLE == DataBasePool.getSessionType(this.dbPoolName)) {
            String sqlTmp = sqlStr.replaceAll("INTO", "INTO \n #rowno,").replaceAll("into", "into \n #rowno,");
            pageSql = "SELECT * FROM (" +
                    "SELECT ROWNUM AS rowno,tableAlias.* FROM (" + sqlTmp + ")tableAlias WHERE ROWNUM <= " + endRowIndex +
                    ") WHERE rowno >" + beginRowIndex;
        } else if (DataBasePoolConfig.DB_TYPE_MYSQL == DataBasePool.getSessionType(this.dbPoolName)) {
            int conditonIndex = getMinConditionIndex(sqlStr);
            if (0 == conditonIndex) {
                pageSql = sqlStr + " LIMIT " + beginRowIndex + "," + pageInfo.getPageSize();
            } else {
                pageSql = sqlStr.substring(0, conditonIndex) + " " + sqlStr.substring(conditonIndex) + " LIMIT " + beginRowIndex + "," + pageInfo.getPageSize();
            }
        } else if (DataBasePoolConfig.DB_TYPE_POSTGRESQL == DataBasePool.getSessionType(this.dbPoolName)) {
            int conditonIndex = getMinConditionIndex(sqlStr);
            if (0 == conditonIndex) {
                pageSql = sqlStr + " LIMIT " + pageInfo.getPageSize() + " OFFSET " + beginRowIndex;
            } else {
                pageSql = sqlStr.substring(0, conditonIndex) + " " + sqlStr.substring(conditonIndex) + " LIMIT " + pageInfo.getPageSize() + ",OFFSET " + beginRowIndex;
            }
        } else {
            rglog.error("不支持的数据库分页查询类型!");
        }
        return pageSql;
    }

    /**
     * 获取having、order及group最近的SQL条件位置
     *
     * @param sqlStr 需要判断的SQL
     * @return 位置
     */
    private int getMinConditionIndex(String sqlStr) {
        String conditionSql = sqlStr.toLowerCase();
        int conditonIndex = Math.min(conditionSql.indexOf("haveing "), conditionSql.indexOf("group "));
        if (conditonIndex < 0) {
            conditonIndex = Math.max(conditonIndex, conditionSql.indexOf("order "));
        } else {
            int compareIndex = Math.min(conditonIndex, conditionSql.indexOf("order "));
            if (compareIndex > 0) {
                conditonIndex = compareIndex;
            }
        }
        if (conditonIndex < 0) {
            conditonIndex = 0;
        }
        return conditonIndex;
    }

    /**
     * 校验分页查询条件对象中是否存在rowno字段
     *
     * @param obj 分页查询条件对象
     * @return true-存在，false-不存在
     */
    private boolean pageQueryInputObjectCheck(Object obj) {
        try {
            Field field = obj.getClass().getDeclaredField("rowno");
            if (null != field) {
                return true;
            }
        } catch (NoSuchFieldException e) {
            rglog.error("分页查询条件对象中缺失rowno字段!");
            return false;
        }
        return true;
    }

    /**
     * 动态SQL解析
     *
     * @param sqlStr 原始SQL字符串
     * @param object SQL对应条件值对应对象
     * @return 动态SQL
     * @throws Exception 异常
     */
    private String parseDynamicSqlString(String sqlStr, Object object) throws Exception {
        Pattern pattern = Pattern.compile("\\s+");
        sqlStr = sqlStr.replaceAll("\\n", " ").replaceAll("\\t", " ").replaceAll(" {2}", " ");
        sqlStr = pattern.matcher(sqlStr).replaceAll(" ");
        rglog.debug("应用配置的SQL语句:{}", sqlStr);
        StringBuilder dynamicStr = new StringBuilder();
        /* 判断SQL中是否存在动态判断条件 */
        String condSuffix = "/>";
        /* 动态SQL条件判断语句起始及截止判断符 */
        String condPrefix = "<if ";
        String conditionStr = StringUtil.subIntercept(sqlStr, condPrefix, condSuffix);
        if (null == conditionStr || conditionStr.isEmpty()) {
            return sqlStr;
        }
        /* 将第一个条件之前的SQL拼到动态SQL前 */
        dynamicStr.append(sqlStr, 0, sqlStr.indexOf(condPrefix));
        String condSqlStr = sqlStr.substring(sqlStr.indexOf(condSuffix) + condSuffix.length());
        /* 解析动态条件，并拼接动态SQL */
        while (true) {
            /* 获取条件属性值(两个"号之间的值) */
            /* 条件判断值分隔符 */
            String quotationMarks = "\"";
            String condString = StringUtil.subIntercept(conditionStr, quotationMarks, quotationMarks);
            /* 校验当前条件是否成立 */
            boolean checkResult = checkConditionValue(condString, object);
            /* 判断是否存在下一个判断条件 */
            conditionStr = StringUtil.subIntercept(condSqlStr, condPrefix, condSuffix);
            if (null == conditionStr || conditionStr.isEmpty()) {
                if (checkResult) {
                    dynamicStr.append(condSqlStr);
                } else {
                    /* 获取去掉不满足条件的其它字符串 */
                    dynamicStr.append(getLastCondWhereString(condSqlStr));
                    /* 校验SQL语句是否存在WHERE条件，且WHRER后无其它信息 */
                    String whereString = dynamicStr.toString().replaceAll("\\t", " ").replaceAll("\\n", " ");
                    /* SQL条件查询WHERE */
                    String upperWhere = " WHERE ";
                    int offset = whereString.indexOf(upperWhere);
                    if (offset < 0) {
                        String lowerWhere = " where ";
                        offset = whereString.indexOf(lowerWhere);
                    }
                    if (offset >= 0) {
                        String lastStr = whereString.substring(offset + upperWhere.length());
                        if (lastStr.trim().isEmpty()) {
                            dynamicStr.append("1 = 1");
                        }
                    }
                }
                break;
            } else {
                if (checkResult) {
                    dynamicStr.append(condSqlStr, 0, condSqlStr.indexOf(condPrefix));
                }
                condSqlStr = condSqlStr.substring(condSqlStr.indexOf(condSuffix) + condSuffix.length());
            }
        }
        dynamicStr = new StringBuilder(dynamicStr.toString().replaceAll("\\n", " ").replaceAll("\\t", " ").replaceAll(" {2}", " "));
        rglog.debug("动态解析后的SQL语句:{}", dynamicStr.toString());
        return dynamicStr.toString();
    }

    /**
     * 获取不满足条件后的其它正常条件字符串
     *
     * @param sqlStr 原始字符串
     * @return 不满足条件后的其它正常条件字符串
     */
    private String getLastCondWhereString(String sqlStr) {
        String returnStr = "";
        String tmpStr = sqlStr.toLowerCase().replaceAll("\\t", " ").replaceAll("\\n", " ");
        int beginOffset = Math.min(tmpStr.indexOf(condAndSeparator), tmpStr.indexOf(condOrSeparator));
        if (beginOffset < 0) {
            /* 再取AND与OR之间的最大值 */
            beginOffset = Math.max(tmpStr.indexOf(condAndSeparator), tmpStr.indexOf(condOrSeparator));
            if (beginOffset < 0) {
                while (tmpStr.length() > 0) {
                    if (tmpStr.startsWith(" order ") || tmpStr.startsWith(" group ") || tmpStr.startsWith(" having ")) {
                        return sqlStr.substring(sqlStr.length() - tmpStr.length());
                    }
                    tmpStr = tmpStr.substring(1);
                }
                return returnStr;
            }
        }
        String nextTmpStr = tmpStr.substring(beginOffset + 4);
        while (nextTmpStr.length() > 0) {
            if (nextTmpStr.startsWith(condAndSeparator) || nextTmpStr.startsWith(condOrSeparator)) {
                return sqlStr.substring(sqlStr.length() - nextTmpStr.length());
            } else if (nextTmpStr.startsWith(between)) {
                nextTmpStr = nextTmpStr.substring(nextTmpStr.indexOf(condAndSeparator) + condAndSeparator.length());
                continue;
            } else if (nextTmpStr.startsWith(leftBracket)) {
                int leftBracketNum = 1;
                int rightBracketNum = 0;
                nextTmpStr = nextTmpStr.substring(1);
                while (leftBracketNum != rightBracketNum) {
                    if (nextTmpStr.startsWith(leftBracket)) {
                        leftBracketNum++;
                    } else if (nextTmpStr.startsWith(rightBracket)) {
                        rightBracketNum++;
                    }
                    nextTmpStr = nextTmpStr.substring(1);
                }
                continue;
            } else if (nextTmpStr.startsWith(" order ") || nextTmpStr.startsWith(" group ") || nextTmpStr.startsWith(" having ")) {
                return sqlStr.substring(sqlStr.length() - nextTmpStr.length());
            }
            nextTmpStr = nextTmpStr.substring(1);
        }
        return returnStr;
    }

    /**
     * 条件判断
     *
     * @param condString 条件字符串
     * @param object     条件字符串中KEY对应的对象
     * @return true-条件成立,false-条件不成立
     * @throws Exception 异常
     */
    private boolean checkConditionValue(String condString, Object object) throws Exception {
        String condRelation = condAndSeparator.trim();
        if (null == condString || condString.isEmpty()) {
            return true;
        }
        /* 根据条件与或条件拆分判断条件项 */
        List<String> condList = new ArrayList<>();
        if (condString.contains(condAndSeparator)) {
            condList = Arrays.asList(condString.split(condAndSeparator));
        } else if (condString.contains(condAndSeparator.toUpperCase())) {
            condList = Arrays.asList(condString.split(condAndSeparator.toUpperCase()));
        } else if (condString.contains(condOrSeparator)) {
            condList = Arrays.asList(condString.split(condOrSeparator));
            condRelation = condOrSeparator.trim();
        } else if (condString.contains(condOrSeparator.toUpperCase())) {
            condList = Arrays.asList(condString.split(condOrSeparator.toUpperCase()));
            condRelation = condOrSeparator.trim();
        } else {
            condList.add(condString);
        }
        boolean checkResult = true;
        for (String cond : condList) {
            /* 条件判断等于及不等于定义 */
            String condEqualSign = "=";
            String condNotEqualSign = "!=";
            String separator = cond.contains(condNotEqualSign) ? condNotEqualSign : condEqualSign;
            String key = cond.split(separator)[0].trim();
            String value = cond.split(separator)[1].trim();
            if (separator.equals(condNotEqualSign)) {
                checkResult &= checkCondNotEqualValue(key, value, condRelation, object);
            } else {
                checkResult &= checkCondEqualValue(key, value, condRelation, object);
            }
        }
        return checkResult;
    }

    /**
     * 等于条件判断
     *
     * @param key          条件KEY
     * @param value        条件VALUE
     * @param condRelation 逻辑与关系 and 或者 or
     * @param object       成员变量对象
     * @return true-条件成立,false-条件不成立
     * @throws Exception 异常
     */
    private boolean checkCondEqualValue(String key, String value, String condRelation, Object object) throws Exception {
        String keyValue = getCondKeyValue(key, object);
        if ("null".equalsIgnoreCase(value) || "''".equals(value) || value.isEmpty()) {
            if (condAndSeparator.trim().equals(condRelation)) {
                return null == keyValue;
            } else if (condOrSeparator.trim().equals(condRelation)) {
                return null == keyValue;
            }
        } else if (value.startsWith("$")) {
            String checkValue = getCondKeyValue(value.substring(1), object);
            if (condAndSeparator.trim().equals(condRelation)) {
                if ((null != keyValue && null == checkValue) || (null == keyValue && null != checkValue)) {
                    return false;
                } else if (null != keyValue && !keyValue.equals(checkValue)) {
                    return false;
                }
            } else if (condOrSeparator.trim().equals(condRelation)) {
                if (null == keyValue && null == checkValue) {
                    return true;
                } else {
                    return null != keyValue && keyValue.equals(checkValue);
                }
            }
        } else {
            if (condAndSeparator.trim().equals(condRelation)) {
                if (!value.equals(keyValue)) {
                    return false;
                }
            } else if (condOrSeparator.trim().equals(condRelation)) {
                return value.equals(keyValue);
            }
        }
        return false;
    }

    /**
     * 不等于条件判断
     *
     * @param key          条件KEY
     * @param value        条件VALUE
     * @param condRelation 逻辑与关系 and 或者 or
     * @param object       成员变量对象
     * @return true-条件成立,false-条件不成立
     * @throws Exception 异常
     */
    private boolean checkCondNotEqualValue(String key, String value, String condRelation, Object object) throws Exception {
        String keyValue = getCondKeyValue(key, object);
        if ("null".equalsIgnoreCase(value) || "''".equals(value) || value.isEmpty()) {
            if (condAndSeparator.trim().equals(condRelation)) {
                return null != keyValue;
            }
            if (condOrSeparator.trim().equals(condRelation)) {
                return null != keyValue;
            }
        } else if (value.startsWith("$")) {
            String checkValue = getCondKeyValue(value.substring(1), object);
            if (condAndSeparator.trim().equals(condRelation)) {
                if (null == keyValue && null == checkValue) {
                    return false;
                } else {
                    return null == keyValue || !keyValue.equals(checkValue);
                }
            } else if (condOrSeparator.trim().equals(condRelation)) {
                if ((null != keyValue && null == checkValue) || (null == keyValue && null != checkValue)) {
                    return true;
                } else {
                    return null != keyValue && !keyValue.equals(checkValue);
                }
            }
        } else {
            if (condAndSeparator.trim().equals(condRelation)) {
                return !value.equals(keyValue);
            } else if (condOrSeparator.trim().equals(condRelation)) {
                return !value.equals(keyValue);
            }
        }
        return false;
    }

    /**
     * 根据成员变量名获取对象中对应的值
     *
     * @param fieldName 成员变量名
     * @param object    对象
     * @return 成员变量值
     * @throws Exception 异常
     */
    private String getCondKeyValue(String fieldName, Object object) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        if (null == object) {
            /* 节点值从内部树获取 */
            return xmlTreeUtil.getXmlTreeStringValue(fieldName);
        } else {
            Field[] fields = object.getClass().getDeclaredFields();
            Optional<Field> fieldOpt = Arrays.stream(fields).filter(item -> item.getName().equals(StringUtil.underScoreToCamelString(fieldName))).findFirst();
            if (fieldOpt.isPresent()) {
                Field field = fieldOpt.get();
                field.setAccessible(true);
                if (null != field.get(object)) {
                    return String.valueOf(fieldOpt.get().get(object));
                }
            }
        }
        return null;
    }
}
